package br.uvv.sao.domain;

import java.io.Serializable;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Version;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;

import br.uvv.sao.enums.TipoGrauDificuldade;

@Entity
@Table(name="sao_questao_base")
public class QuestaoBase implements Serializable {
	private static final long serialVersionUID = 7034003176961880326L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	@Version
	private Integer version = 0;

	@Column(name = "codigo", nullable = false, unique = true, length = 30)
	private String codigo;

	@Column(name = "cabecalho", nullable = false, length = 4000)
	private String cabecalho;

	@Enumerated(EnumType.ORDINAL)
	@Column(name = "grau_dificuldade")
	private TipoGrauDificuldade grauDificuldade;

	@ManyToOne
	@JoinColumn(name = "palavra_chave_id", nullable = false)
	private PalavraChave palavraChave;
	
	@ManyToOne
	@JoinColumn(name = "professor_id")
	private Professor professor;
	
	@OneToOne(fetch = FetchType.LAZY)
	@OnDelete(action=OnDeleteAction.CASCADE)
	@JoinColumn(name = "alternativa_correta_id", nullable = true)
	@Cascade(CascadeType.SAVE_UPDATE)
	private AlternativaBase alternativaCorreta;
	
	@OneToMany(mappedBy = "questaoBase", targetEntity = AlternativaBase.class, fetch = FetchType.LAZY)
	@OnDelete(action=OnDeleteAction.CASCADE)
	@Cascade(CascadeType.ALL)
	private List<AlternativaBase> alternativas;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Integer getVersion() {
		return version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	public String getCodigo() {
		return codigo;
	}

	public void setCodigo(String codigo) {
		this.codigo = codigo;
	}

	public String getCabecalho() {
		return cabecalho;
	}

	public void setCabecalho(String cabecalho) {
		this.cabecalho = cabecalho;
	}

	public TipoGrauDificuldade getGrauDificuldade() {
		return grauDificuldade;
	}

	public void setGrauDificuldade(TipoGrauDificuldade grauDificuldade) {
		this.grauDificuldade = grauDificuldade;
	}

	public PalavraChave getPalavraChave() {
		return palavraChave;
	}

	public void setPalavraChave(PalavraChave palavraChave) {
		this.palavraChave = palavraChave;
	}

	public AlternativaBase getAlternativaCorreta() {
		return alternativaCorreta;
	}
	
	public void setAlternativaCorreta(AlternativaBase alternativaCorreta) {
		this.alternativaCorreta = alternativaCorreta;
	}
	
	public List<AlternativaBase> getAlternativas() {
		return alternativas;
	}
	
	public void setAlternativas(List<AlternativaBase> alternativas) {
		this.alternativas = alternativas;
	}
	
	public Professor getProfessor() {
		return professor;
	}

	public void setProfessor(Professor professor) {
		this.professor = professor;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime
				* result
				+ ((alternativaCorreta == null) ? 0 : alternativaCorreta
						.hashCode());
		result = prime * result
				+ ((alternativas == null) ? 0 : alternativas.hashCode());
		result = prime * result
				+ ((cabecalho == null) ? 0 : cabecalho.hashCode());
		result = prime * result + ((codigo == null) ? 0 : codigo.hashCode());
		result = prime * result
				+ ((grauDificuldade == null) ? 0 : grauDificuldade.hashCode());
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result
				+ ((palavraChave == null) ? 0 : palavraChave.hashCode());
		result = prime * result
				+ ((professor == null) ? 0 : professor.hashCode());
		result = prime * result + ((version == null) ? 0 : version.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		QuestaoBase other = (QuestaoBase) obj;
		if (alternativaCorreta == null) {
			if (other.alternativaCorreta != null)
				return false;
		} else if (!alternativaCorreta.equals(other.alternativaCorreta))
			return false;
		if (alternativas == null) {
			if (other.alternativas != null)
				return false;
		} else if (!alternativas.equals(other.alternativas))
			return false;
		if (cabecalho == null) {
			if (other.cabecalho != null)
				return false;
		} else if (!cabecalho.equals(other.cabecalho))
			return false;
		if (codigo == null) {
			if (other.codigo != null)
				return false;
		} else if (!codigo.equals(other.codigo))
			return false;
		if (grauDificuldade != other.grauDificuldade)
			return false;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (palavraChave == null) {
			if (other.palavraChave != null)
				return false;
		} else if (!palavraChave.equals(other.palavraChave))
			return false;
		if (professor == null) {
			if (other.professor != null)
				return false;
		} else if (!professor.equals(other.professor))
			return false;
		if (version == null) {
			if (other.version != null)
				return false;
		} else if (!version.equals(other.version))
			return false;
		return true;
	}
}
